﻿using KineBall.GameLogic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace KineBall.Rendering
{
    class RectangleModel
    {
        public VertexBuffer VertexBuffer { get { return _vertexBuffer; } }
        private VertexBuffer _vertexBuffer;

        public RectangleModel(GraphicsDevice graphicsDevice)
        {
            VertexPositionColor[] vertexArray = new VertexPositionColor[5];
            vertexArray[0] = new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0), new Color(0f, 255f, 0));
            vertexArray[1] = new VertexPositionColor(new Vector3(0.5f, -0.5f, 0), new Color(0f, 255f, 0));
            vertexArray[2] = new VertexPositionColor(new Vector3(0.5f, 0.5f, 0), new Color(0f, 255f, 0));
            vertexArray[3] = new VertexPositionColor(new Vector3(-0.5f, 0.5f, 0), new Color(0f, 255f, 0));
            vertexArray[4] = new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0), new Color(0f, 255f, 0));

            _vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionColor.VertexDeclaration, vertexArray.Length, BufferUsage.None);
            _vertexBuffer.SetData<VertexPositionColor>(vertexArray);
        }
    }

    class BallFollowerModel
    {
        public VertexBuffer VertexBuffer { get { return _vertexBuffer; } }
        private VertexBuffer _vertexBuffer;

        //new Color(128, 255, 255

        public BallFollowerModel(GraphicsDevice graphicsDevice)
        {
            VertexPositionColor[] vertexArray = new VertexPositionColor[5];
            vertexArray[0] = new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0), Color.Cyan);
            vertexArray[1] = new VertexPositionColor(new Vector3(0.5f, -0.5f, 0), Color.Cyan);
            vertexArray[2] = new VertexPositionColor(new Vector3(0.5f, 0.5f, 0), Color.Cyan);
            vertexArray[3] = new VertexPositionColor(new Vector3(-0.5f, 0.5f, 0), Color.Cyan);
            vertexArray[4] = new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0), Color.Cyan);

            _vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionColor.VertexDeclaration, vertexArray.Length, BufferUsage.None);
            _vertexBuffer.SetData<VertexPositionColor>(vertexArray);
        }
    }

    class LineModel
    {
        public VertexBuffer VertexBuffer { get { return _vertexBuffer; } }
        private VertexBuffer _vertexBuffer;

        public LineModel(GraphicsDevice graphicsDevice)
        {
            VertexPositionColor[] vertexArray = new VertexPositionColor[2];
            vertexArray[0] = new VertexPositionColor(new Vector3(0f, 0f, -0.5f), new Color(0f, 255f, 0));
            vertexArray[1] = new VertexPositionColor(new Vector3(0f, 0f, 0.5f), new Color(0f, 255f, 0));

            _vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionColor.VertexDeclaration, vertexArray.Length, BufferUsage.None);
            _vertexBuffer.SetData<VertexPositionColor>(vertexArray);
        }
    }

    public class GameFieldModel
    {
        private RectangleModel rectangleModel;
        private BallFollowerModel ballFollowerModel;
        private LineModel lineModel;

        private Matrix RectanglesScale;
        private Matrix[] RectanglesTranslation;

        private Matrix LinesScale;
        private Matrix[] LinesTranslation;

        public GameFieldModel(GraphicsDevice graphicsDevice, GameField gameField)
        {
            rectangleModel = new RectangleModel(graphicsDevice);
            ballFollowerModel = new BallFollowerModel(graphicsDevice);
            lineModel = new LineModel(graphicsDevice);

            RectanglesScale = Matrix.CreateScale(new Vector3(gameField.Width, gameField.Height, 1));
            RectanglesTranslation = new Matrix[gameField.rectangles.Length];

            for (int i = 0; i < gameField.rectangles.Length; i++)
            {
                RectanglesTranslation[i] = Matrix.CreateTranslation(gameField.rectangles[i]);
            }

            LinesScale = Matrix.CreateScale(new Vector3(1f, 1f, gameField.Depth - 1));

            LinesTranslation = new Matrix[4];
            LinesTranslation[0] = Matrix.CreateTranslation(new Vector3(gameField.Width * 0.5f, gameField.Height * 0.5f, 0));
            LinesTranslation[1] = Matrix.CreateTranslation(new Vector3(-gameField.Width * 0.5f, gameField.Height * 0.5f, 0));
            LinesTranslation[2] = Matrix.CreateTranslation(new Vector3(-gameField.Width * 0.5f, -gameField.Height * 0.5f, 0));
            LinesTranslation[3] = Matrix.CreateTranslation(new Vector3(gameField.Width * 0.5f, -gameField.Height * 0.5f, 0));
        }

        public void Draw(BasicEffect effect, GraphicsDevice graphicsDevice, GameField gameField, Vector3 ballPosition)
        {
            effect.VertexColorEnabled = true;
            effect.TextureEnabled = false;
            effect.LightingEnabled = false;

            //Drawing Rectangles
            for (int i = 0; i < gameField.rectangles.Length; i++)
            {
                effect.World = RectanglesScale * RectanglesTranslation[i];

                effect.CurrentTechnique.Passes[0].Apply();

                graphicsDevice.SetVertexBuffer(rectangleModel.VertexBuffer);
                graphicsDevice.DrawPrimitives(PrimitiveType.LineStrip, 0, 4);
            }

            // Drawing depth Lines
            for(int i = 0; i < 4; i++)
            {
                effect.World = LinesScale * LinesTranslation[i];
                effect.CurrentTechnique.Passes[0].Apply();

                graphicsDevice.SetVertexBuffer(lineModel.VertexBuffer);
                graphicsDevice.DrawPrimitives(PrimitiveType.LineStrip, 0, 1);
            }

            // Drawing ballFollower
            effect.World = Matrix.CreateScale(new Vector3(gameField.Width, gameField.Height, 1)) *
                               Matrix.CreateTranslation(new Vector3(0, 0, ballPosition.Z));

            effect.CurrentTechnique.Passes[0].Apply();

            graphicsDevice.SetVertexBuffer(ballFollowerModel.VertexBuffer);
            graphicsDevice.DrawPrimitives(PrimitiveType.LineStrip, 0, 4);

            effect.VertexColorEnabled = false;
        }
    }
}